/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package services.emprestimo;

import data.Dinheiro;
import data.Empregado;
import data.Emprestimo;
import data.TipoSolicitante;
import services.BaseServices;
import util.Const;

/**
 *
 * @author
 * PedroLZ
 */
public class EmprestimoServices extends BaseServices
{
	private static final String
			ERR_NUM_PARCELAS_INVALIDO				= "ERR_NUM_PARCELAS_INVALIDO",
			ERR_NUM_PARCELAS_MENOR_QUE_O_MINIMO		= "ERR_NUM_PARCELAS_MENOR_QUE_O_MINIMO",
			ERR_NUM_PARCELAS_MAIOR_QUE_O_MAXIMO		= "ERR_NUM_PARCELAS_MAIOR_QUE_O_MAXIMO",
			ERR_VALOR_EMPRESTIMO_VAZIO				= "ERR_VALOR_EMPRESTIMO_VAZIO",
			ERR_VALOR_SOLICITADO_MAIOR_QUE_O_LIMITE	= "ERR_VALOR_SOLICITADO_MAIOR_QUE_O_LIMITE",
			ERR_SOLICITANTE_NAO_TEM_TIPO_VALIDO		= "ERR_SOLICITANTE_NAO_TEM_TIPO_VALIDO";
	
	static public double obterJurosSolicitacaoEmprestimo( Emprestimo emprestimo )
	{
		TipoSolicitante tipoSolicitante = getTipoSolicitante( emprestimo.getSolicitante() );
		validarSolicitacaoEmprestimo( emprestimo, tipoSolicitante );
		
		return( getJurosSolicitacaoEmprestimo( emprestimo ) );
	}

	//-------------------------------------------------------------------------
	// métodos private
	//-------------------------------------------------------------------------	
	private static void validarSolicitacaoEmprestimo( Emprestimo emprestimo, TipoSolicitante tipoSolicitante )
	{
		validaNumeroParcelas( emprestimo.getNumParcelas() );
		validaTipoSolicitante( tipoSolicitante );
		validaValorEmprestimo( emprestimo.getValor(), emprestimo.getSolicitante(), tipoSolicitante );
	}

	private static void validaNumeroParcelas( int numParcelas )
	{
		check( numParcelas >= 0, Const.getString(ERR_NUM_PARCELAS_INVALIDO) );
		
		String msgErro = String.format( Const.getString(ERR_NUM_PARCELAS_MENOR_QUE_O_MINIMO), Emprestimo.NUM_PARCELAS_MIN );
		check( numParcelas >= Emprestimo.NUM_PARCELAS_MIN, msgErro );
		
		msgErro = String.format( Const.getString(ERR_NUM_PARCELAS_MAIOR_QUE_O_MAXIMO), Emprestimo.NUM_PARCELAS_MAX );
		check( numParcelas <= Emprestimo.NUM_PARCELAS_MAX, msgErro );
	}

	private static void validaTipoSolicitante(TipoSolicitante tipoSolicitante)
	{
		check( tipoSolicitante != null, Const.getString( ERR_SOLICITANTE_NAO_TEM_TIPO_VALIDO ) );
	}

	private static void validaValorEmprestimo( Dinheiro valor, Empregado solicitante, TipoSolicitante tipoSolicitante )
	{
		check( valor != null, Const.getString(ERR_VALOR_EMPRESTIMO_VAZIO) );
		
		Dinheiro limiteEmprestimo = tipoSolicitante.getLimiteEmprestimo( solicitante );
		check( !valor.isMaiorQue( limiteEmprestimo ),
				String.format( Const.getString( ERR_VALOR_SOLICITADO_MAIOR_QUE_O_LIMITE ), limiteEmprestimo ) );
	}
	
	private static TipoSolicitante getTipoSolicitante( Empregado solicitante )
	{
		for( TipoSolicitante umTipoSolicitante : TiposDeSolicitante.getTodos() )
		{
			if( umTipoSolicitante.isSolicitanteDesteTipo( solicitante ) )
				return( umTipoSolicitante );
		}
		return( null );
	}

	private static double getJurosSolicitacaoEmprestimo( Emprestimo emprestimo )
	{
		if( emprestimo.isNumParcelasEntre( 1, 3 ) )	
			return 0.05;
		else if( emprestimo.isNumParcelasEntre( 4, 9 ) )
			return 0.065;
		else if( emprestimo.isNumParcelasEntre( 10, 12 ) )
			return 0.08;
		else if( emprestimo.isNumParcelasEntre( 13, 18 ) )
			return 0.10;
		else
			return 0.0;
	}	
}
